package com.sikeda.imagecomposetool;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.sikeda.imagecomposetool.entity.Coordinates;
import com.sikeda.imagecomposetool.utils.ArithUtil;
import com.sikeda.imagecomposetool.utils.GlideUtil;
import com.sikeda.imagecomposetool.utils.LogUtil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.finalteam.galleryfinal.GalleryFinal;
import cn.finalteam.galleryfinal.model.PhotoInfo;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {

    private int IMAGE_WIDTH = 3508;
    private int IMAGE_HEIGHT = 4961;//11.81倍
    private int emptyWidth = 150;
    private int emptyHeight = 80;
    private int currentWidth;
    private int currentHeight;
    private int textSize;
    private EditText et_margin_height, et_margin_width, et_text_size, et_width, et_height, et_image_sava_path;
    private int bitmapBgColor = Color.parseColor("#dedede");
    private int textColor = Color.GRAY;
    private int[][] bitmapPos = new int[8][2];
    private String[] dataStr = new String[8];
    private List<Coordinates> connerLineList = new ArrayList<>();
    private String filePath = "/sdcard/compose/";
    private final int REQUEST_CODE_GALLERY_BYTRAVEL = 1002;
    private List<PhotoInfo> imageSelectedList;
    private List<String> paths = new ArrayList<String>();

    private TextView btn_select;
    private ProgressDialog dialog;
    private LinearLayout ll_iamges_selected;
    private ArrayList<String> composedList = new ArrayList<>();
    private boolean isEnd;
    private Subscriber<String> bitmapSubscriber;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 100) {
                LogUtil.i("info", "msg.what == 100");
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                }
                if (isEnd) {
                    Intent intent = new Intent(MainActivity.this, ImageComposedActivity.class);
                    intent.putStringArrayListExtra("photos", composedList);
                    startActivity(intent);
                }
            }
            if (msg.what == 22) {
                Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_LONG).show();
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn_select = (TextView) findViewById(R.id.btn_select);
        ll_iamges_selected = (LinearLayout) findViewById(R.id.ll_iamges_selected);


        et_margin_height = (EditText) findViewById(R.id.et_margin_height);
        et_margin_width = (EditText) findViewById(R.id.et_margin_width);
        et_text_size = (EditText) findViewById(R.id.et_text_size);
        et_width = (EditText) findViewById(R.id.et_width);
        et_height = (EditText) findViewById(R.id.et_height);
        et_image_sava_path = (EditText) findViewById(R.id.et_image_sava_path);
        imageSelectedList = new ArrayList<>();

        showDialog();
        findViewById(R.id.btn_select).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    String[] permissions = {
                            Manifest.permission.READ_EXTERNAL_STORAGE
                    };
                    ActivityCompat.requestPermissions(MainActivity.this, permissions, 100);
                } else {
                    GalleryFinal.openGalleryMuti(REQUEST_CODE_GALLERY_BYTRAVEL, AppContext.getInstance().getFunctionConfig(imageSelectedList, 1000), new MyOnHandlerResultCallBack());//打开多图选择器，并设置已选项目跟选择结束回调
                }
            }
        });

        RadioGroup radioGroupBitBg = (RadioGroup) findViewById(R.id.radiogrop_bitmap_bg);
        radioGroupBitBg.check(R.id.radiobtn_white);
        radioGroupBitBg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                switch (i) {
                    case R.id.radiobtn_white:
                        bitmapBgColor = Color.parseColor("#dedede");
                        break;
                    case R.id.radiobtn_black:
                        bitmapBgColor = Color.BLACK;
                        break;
                    case R.id.radiobtn_theme:
                        bitmapBgColor = getResources().getColor(R.color.colorPrimaryDark);
                        break;
                }
            }
        });
        RadioGroup radiogrop_text_bg = (RadioGroup) findViewById(R.id.radiogrop_text_bg);
        radiogrop_text_bg.check(R.id.radiobtn_gray);
        radiogrop_text_bg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                switch (i) {
                    case R.id.radiobtn_gray:
                        textColor = Color.GRAY;
                        break;
                    case R.id.radiobtn_text_black:
                        textColor = Color.BLACK;
                        break;
                    case R.id.radiobtn_text_theme:
                        textColor = getResources().getColor(R.color.colorPrimaryDark);
                        break;
                }
            }
        });


        findViewById(R.id.btn_compose).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (imageSelectedList.size() == 0) {
                    Toast.makeText(MainActivity.this, "请先选择图片！", Toast.LENGTH_SHORT).show();
                    return;
                }
                composedList.clear();
                getSize();
                if (emptyWidth == 0 || emptyHeight == 0 || textSize == 0 || IMAGE_WIDTH == 0 || IMAGE_HEIGHT == 0 || filePath.equals("")) {
                    return;
                }
                if (dialog != null && !dialog.isShowing()) {
                    dialog.show();
                }
                paths.clear();

                bitmapSubscriber = new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        LogUtil.e("info", "rxjava  onCompleted");
                        Message message = Message.obtain();
                        message.what = 100;
                        handler.sendMessage(message);
                    }

                    @Override
                    public void onError(Throwable e) {
                        LogUtil.e("info", "rxjava  onError");
                        if (dialog != null && dialog.isShowing()) {
                            dialog.dismiss();
                        }
                        Toast.makeText(MainActivity.this, "不可预知的错误！", Toast.LENGTH_LONG).show();
                    }

                    @Override
                    public void onNext(String bitmap) {
                        LogUtil.e("info", "rxjava  onNext");

                    }
                };

                Observable.create(new Observable.OnSubscribe<String>() {

                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        for (PhotoInfo info : imageSelectedList) {
                            paths.add(info.getPhotoPath());
                            if (paths.size() == 8) {
                                createBitMaps(paths);//合成并保存
                                paths.clear();
                            }
                        }
                        createBitMaps(paths);//合成并保存 最后未合成的剩余不足8张时
                        isEnd = true;
                        imageSelectedList.clear();

                        subscriber.onCompleted();
                    }

                }).subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(bitmapSubscriber);

            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 100 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            GalleryFinal.openGalleryMuti(REQUEST_CODE_GALLERY_BYTRAVEL, AppContext.getInstance().getFunctionConfig(imageSelectedList, 1000), new MyOnHandlerResultCallBack());//打开多图选择器，并设置已选项目跟选择结束回调
        }
    }

    private void getSize() {//根据配置动态计算间距，位置等信息
        if (TextUtils.isEmpty(et_width.getText().toString())) {
            Toast.makeText(this, "请配置图片宽度", Toast.LENGTH_SHORT).show();
            IMAGE_WIDTH = 0;
            return;
        }
        if (TextUtils.isEmpty(et_height.getText().toString())) {
            Toast.makeText(this, "请配置图片高度", Toast.LENGTH_SHORT).show();
            IMAGE_HEIGHT = 0;
            return;
        }
        if (TextUtils.isEmpty(et_image_sava_path.getText().toString())) {
            Toast.makeText(this, "请配置图片保存路径", Toast.LENGTH_SHORT).show();
            textSize = 0;
            return;
        }

        if (TextUtils.isEmpty(et_margin_width.getText().toString())) {
            Toast.makeText(this, "请配置图片左右间距", Toast.LENGTH_SHORT).show();
            emptyWidth = 0;
            return;
        }
        if (TextUtils.isEmpty(et_margin_height.getText().toString())) {
            Toast.makeText(this, "请配置图片上下间距", Toast.LENGTH_SHORT).show();
            emptyHeight = 0;
            return;
        }
        if (TextUtils.isEmpty(et_text_size.getText().toString())) {
            Toast.makeText(this, "请配置日期文字大小", Toast.LENGTH_SHORT).show();
            filePath = "";
            return;
        }

        IMAGE_WIDTH = Integer.parseInt(et_width.getText().toString());
        IMAGE_HEIGHT = Integer.parseInt(et_height.getText().toString());
        filePath = et_image_sava_path.getText().toString();

        emptyWidth = Integer.parseInt(et_margin_width.getText().toString());
        emptyHeight = Integer.parseInt(et_margin_height.getText().toString());
        textSize = Integer.parseInt(et_text_size.getText().toString());

        currentWidth = (IMAGE_WIDTH - emptyWidth - 2 * textSize * 7 / 3) / 2;//textSize * 7 / 3 文字左边要留4 / 3 文字宽度的空白块
        currentHeight = (IMAGE_HEIGHT - IMAGE_HEIGHT / 464 * 46) / 4 - emptyHeight;

        //图片绘制的起点
        bitmapPos = new int[][]{
                {textSize * 7 / 3, 0}, {IMAGE_WIDTH - currentWidth, 0},
                {textSize * 7 / 3, currentHeight + emptyHeight}, {IMAGE_WIDTH - currentWidth, currentHeight + emptyHeight},
                {textSize * 7 / 3, 2 * (currentHeight + emptyHeight)}, {IMAGE_WIDTH - currentWidth, 2 * (currentHeight + emptyHeight)},
                {textSize * 7 / 3, 3 * (currentHeight + emptyHeight)}, {IMAGE_WIDTH - currentWidth, 3 * (currentHeight + emptyHeight)}
        };

        LogUtil.i("info", "每张图片的宽度" + currentWidth + "");
        LogUtil.i("info", "每张图片的高度" + currentHeight + "");
        LogUtil.i("info", "比例" + ArithUtil.div(currentWidth, currentHeight) + "");

    }


    private void showDialog() {
        dialog = new ProgressDialog(this);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage("图片合成中...");
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                if (bitmapSubscriber != null) {
                    bitmapSubscriber.unsubscribe();
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (imageSelectedList.size() == 0) {
            btn_select.setText("选择图片");
        } else {
            btn_select.setText("选择图片[已选择" + imageSelectedList.size() + "张]");
        }
        dynamicAddImageViews(imageSelectedList);
    }

    private void dynamicAddImageViews(List<PhotoInfo> resultList) {

        ll_iamges_selected.removeAllViews();
        ImageView imageView;
        LinearLayout.LayoutParams params;
        if (resultList != null && resultList.size() != 0) {
            for (int i = 0; i < resultList.size(); i++) {
                imageView = new ImageView(this);

                params = new LinearLayout.LayoutParams(130, 130);
                params.setMargins(0, 5, 15, 15);
                imageView.setLayoutParams(params);
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                //图片制作时间
               /* try {
                    ExifInterface exif = new ExifInterface(resultList.get(i).getPhotoPath());
                    if (exif.getAttribute(ExifInterface.TAG_DATETIME) != null && !exif.getAttribute(ExifInterface.TAG_DATETIME).equals("")) {
                        dataStr[i] = exif.getAttribute(ExifInterface.TAG_DATETIME).substring(0, exif.getAttribute(ExifInterface.TAG_DATETIME).indexOf(" "));
                        LogUtil.e("info", "图片制作时间：" + exif.getAttribute(ExifInterface.TAG_DATETIME));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }*/

                ll_iamges_selected.addView(imageView, params);
                //使用ImageLoader加载本地图片
                GlideUtil.loadFile(resultList.get(i).getPhotoPath(), imageView);
            }
        }

    }

    class MyOnHandlerResultCallBack implements GalleryFinal.OnHanlderResultCallback {
        @Override
        public void onHanlderSuccess(int reqeustCode, List<PhotoInfo> resultList) {
            imageSelectedList.clear();
            imageSelectedList.addAll(resultList);
            for (PhotoInfo f : resultList) {
                LogUtil.e("info", f.getPhotoPath());
            }
            if (imageSelectedList.size() == 0) {
                btn_select.setText("选择图片");
            } else {
                btn_select.setText("选择图片[已选择" + imageSelectedList.size() + "张]");
            }
            dynamicAddImageViews(resultList);
        }

        @Override
        public void onHanlderFailure(int requestCode, String errorMsg) {

        }

    }

    private Bitmap createBitMaps(List<String> imagePath) {
        if (imagePath == null || imagePath.size() == 0) {
            return null;
        }
        long start = System.currentTimeMillis();

        //创建一个新的指定长度宽度一样的位图
        Bitmap newb = Bitmap.createBitmap(IMAGE_WIDTH, IMAGE_HEIGHT, Bitmap.Config.ARGB_8888);
        Canvas cv = new Canvas(newb);
        cv.drawColor(bitmapBgColor);

        Bitmap sourceBit;


        //将日期跟空白快填充为白色
        Paint whitePaint = new Paint();
        whitePaint.setColor(Color.WHITE);       //设置画笔颜色
        whitePaint.setStyle(Paint.Style.FILL);  //设置画笔模式为填充
        whitePaint.setStrokeWidth(10f);


        //绘制日期
        Paint textPaint = new Paint();        // 创建画笔
        textPaint.setColor(textColor);        // 设置颜色
        textPaint.setAntiAlias(true);
        textPaint.setStyle(Paint.Style.FILL);   // 设置样式
        textPaint.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/fanzheng.ttf"));
        textPaint.setTextSize(textSize);              // 设置字体大小


        //画边角线
        Paint mPaint = new Paint();             // 创建画笔
        mPaint.setColor(Color.BLACK);           // 画笔颜色 - 黑色
        mPaint.setStyle(Paint.Style.STROKE);    // 填充模式 - 描边
        mPaint.setStrokeWidth(2);              // 边框宽度 - 10
        Path path = new Path();                     // 创建Path

        File file;
        Date date;

        for (int i = 0; i < imagePath.size(); i++) {

            //绘制图片
            sourceBit = BitmapFactory.decodeFile(imagePath.get(i));
            cv.drawBitmap(big(sourceBit), bitmapPos[i][0], bitmapPos[i][1], new Paint());//在 0，0坐标开始画入bitmap1

            //将日期跟空白快填充为白色
            cv.drawRect(bitmapPos[i][0] - textSize * 7 / 3, bitmapPos[i][1], bitmapPos[i][0], bitmapPos[i][1] + currentHeight, whitePaint);

            //获取图片的创建日期
            file = new File(imagePath.get(i));
            date = new Date(file.lastModified());
            dataStr[i] = com.sikeda.imagecomposetool.utils.DateUtils.dateToStr(date);

            //绘制日期
            if (dataStr[i] != null && !dataStr[i].equals("")) {
                //将画布逆时针旋转90°，px：旋转点的x坐标。     py：旋转点的y坐标。
                cv.rotate(-90, bitmapPos[i][0], bitmapPos[i][1] + currentHeight);

                cv.drawText(dataStr[i], bitmapPos[i][0] + currentHeight - textPaint.measureText(dataStr[i]), bitmapPos[i][1] + currentHeight - 5, textPaint);
                //将画布顺时针旋转90°px：旋转点的x坐标。     py：旋转点的y坐标。
                cv.rotate(90, bitmapPos[i][0], bitmapPos[i][1] + currentHeight);
            }

            //绘制边角线(奇数绘制右边角，偶数绘制)
            if (i % 2 == 0) {//偶数数，画右半边
                if (i != 0) {//首行不画上
                    //右上角：竖直
                    path.moveTo(bitmapPos[i][0] + currentWidth, bitmapPos[i][1] - 5);
                    path.lineTo(bitmapPos[i][0] + currentWidth, bitmapPos[i][1] - 5 - 20);
                    //右上角：水平直
                    path.moveTo(bitmapPos[i][0] + currentWidth + 5, bitmapPos[i][1]);
                    path.lineTo(bitmapPos[i][0] + currentWidth + 5 + 20, bitmapPos[i][1]);
                }

                //右下角：竖直
                path.moveTo(bitmapPos[i][0] + currentWidth, bitmapPos[i][1] + currentHeight + 5);
                path.lineTo(bitmapPos[i][0] + currentWidth, bitmapPos[i][1] + currentHeight + 5 + 20);
                //右下角：水平直
                path.moveTo(bitmapPos[i][0] + currentWidth + 5, bitmapPos[i][1] + currentHeight);
                path.lineTo(bitmapPos[i][0] + currentWidth + 5 + 20, bitmapPos[i][1] + currentHeight);

            } else {//奇数，画左半边
                if (i != 1) {//首行不画上
                    //左上角：竖直
                    path.moveTo(bitmapPos[i][0] - textSize * 7 / 3, bitmapPos[i][1] - 5);
                    path.lineTo(bitmapPos[i][0] - textSize * 7 / 3, bitmapPos[i][1] - 5 - 20);
                    //左上角：水平直
                    path.moveTo(bitmapPos[i][0] - textSize * 7 / 3 - 5, bitmapPos[i][1]);
                    path.lineTo(bitmapPos[i][0] - textSize * 7 / 3 - 5 - 20, bitmapPos[i][1]);
                }

                //左下角：竖直
                path.moveTo(bitmapPos[i][0] - textSize * 7 / 3, bitmapPos[i][1] + currentHeight + 5);
                path.lineTo(bitmapPos[i][0] - textSize * 7 / 3, bitmapPos[i][1] + currentHeight + 5 + 20);
                //左下角：水平直
                path.moveTo(bitmapPos[i][0] - textSize * 7 / 3 - 5, bitmapPos[i][1] + currentHeight);
                path.lineTo(bitmapPos[i][0] - textSize * 7 / 3 - 5 - 20, bitmapPos[i][1] + currentHeight);
            }

            cv.drawPath(path, mPaint);              // 绘制Path
        }
        file = null;
        cv.save(Canvas.ALL_SAVE_FLAG);//保存
        Log.e("info", "canvas use time:" + (System.currentTimeMillis() - start) + "ms");
        saveBitmap(newb, filePath, "合成" + System.currentTimeMillis() + ".jpg");

        return newb;
    }


    // 保存图片
    public boolean saveBitmap(Bitmap mBitmap, String path, String imgName) {
        String sdStatus = Environment.getExternalStorageState();
        if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
            return false;
        }
        FileOutputStream b = null;
        File file = new File(path);
        file.mkdirs();// 创建文件夹
        String fileName = path + imgName;// 图片名字"head.jpg"
        try {
            b = new FileOutputStream(fileName);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件

            Log.i("info", "图片保存本地成功" + path + imgName);
            composedList.add(path + imgName);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭流
                b.flush();
                b.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return true;
    }


    /**
     * Bitmap放大的方法
     */
    private Bitmap big(Bitmap bitmap) {
        Matrix matrix = new Matrix();
        float scaleSize;

        if (bitmap.getWidth() < bitmap.getHeight()) {//如果照片书竖直方向，则旋转90°,旋转后不会影响原图方向，只是显示不同
            // 向右旋转90度，参数为正则向右旋转
            Log.e("info", "需要旋转");
            matrix.postRotate(-90);
            scaleSize = Math.max((float) ArithUtil.div(currentWidth, bitmap.getHeight()), (float) ArithUtil.div(currentHeight, bitmap.getWidth()));
        } else {
            scaleSize = Math.max((float) ArithUtil.div(currentWidth, bitmap.getWidth()), (float) ArithUtil.div(currentHeight, bitmap.getHeight()));
        }
        matrix.postScale(scaleSize, scaleSize); //长和宽放大缩小的比例
        Log.e("info", "scaleSize:" + scaleSize);
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
            bitmap = null;
        }
        return ImageCropWithRect(resizeBmp);
    }


    /**
     * 按长方形裁切图片
     *
     * @param bitmap
     * @return
     */
    public Bitmap ImageCropWithRect(Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }

        int w = bitmap.getWidth(); // 得到图片的宽，高
        int h = bitmap.getHeight();

        int nw = 0, nh = 0, retX = 0, retY = 0;

        if (w > currentWidth) {//裁剪宽
            nw = currentWidth;
            nh = h;
            retX = (w - nw) / 2;
            retY = 0;
        }

        if (h > currentHeight) {
            nw = w;
            nh = currentHeight;
            retX = 0;
            retY = (h - nh) / 2;
        }

        // 下面这句是关键
        Bitmap bmp = Bitmap.createBitmap(bitmap, retX, retY, nw, nh, null,
                false);
        if (bitmap != null && !bitmap.equals(bmp) && !bitmap.isRecycled()) {
            bitmap.recycle();
            bitmap = null;
        }
        return bmp;// Bitmap.createBitmap(bitmap, retX, retY, nw, nh, null,
        // false);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (bitmapSubscriber != null) {
            bitmapSubscriber.unsubscribe();
        }
    }
}
